﻿using System;
using System.IO;

namespace SfsTools.Core
{
    /// <summary>
    /// Represents a directory on a <see cref="FileSystem"/>.
    /// </summary>
    public interface IDirectory : IFileSystemObject
    {
        /// <summary>
        /// Resolves the specified path to a <see cref="IFileSystemObject"/>.
        /// </summary>
        /// <param name="name">The relative or absolute path to resolve.</param>
        /// <returns>The <see cref="IFileSystemObject"/> specified by <paramref name="name"/>.</returns>
        /// <exception cref="ArgumentNullException">The argument <paramref name="name"/> is <see langword="null"/>.</exception>
        /// <exception cref="PathNotFoundException">The specified <see cref="IFileSystemObject"/> cannot be found.</exception>
        IFileSystemObject Resolve(String name);

        /// <summary>
        /// Returns an array containing all <see cref="IDirectory">subdirectories</see>.
        /// </summary>
        /// <returns>An array containing all <see cref="IDirectory">subdirectories</see>.</returns>
        IDirectory[] GetDirectories();

        /// <summary>
        /// Returns an array containing all <see cref="IDirectory">subdirectories</see>.
        /// </summary>
        /// <param name="includeDeleted">Specifies whether to include deleted <see cref="IDirectory">subdirectories</see> as well.</param>
        /// <returns>An array containing all <see cref="IDirectory">subdirectories</see>.</returns>
        IDirectory[] GetDirectories(bool includeDeleted);

        /// <summary>
        /// Returns an array containing all <see cref="IFile"/>s.
        /// </summary>
        /// <returns>An array containing all <see cref="IFile"/>s.</returns>
        IFile[] GetFiles();

        /// <summary>
        /// Returns an array containing all <see cref="IFile"/>s.
        /// </summary>
        /// <param name="includeDeleted">Specifies whether to include deleted <see cref="IFile"/>s as well.</param>
        /// <returns>An array containing all <see cref="IFile"/>s.</returns>
        IFile[] GetFiles(bool includeDeleted);

        /// <summary>
        /// Returns an array containing all <see cref="IFileSystemObject"/>s.
        /// </summary>
        /// <returns>An array containing all <see cref="IFileSystemObject"/>s.</returns>
        IFileSystemObject[] GetObjects();

        /// <summary>
        /// Returns an array containing all <see cref="IFileSystemObject"/>s.
        /// </summary>
        /// <param name="includeDeleted">Specifies whether to include deleted <see cref="IFileSystemObject"/>s as well.</param>
        /// <returns>An array containing all <see cref="IFileSystemObject"/>s.</returns>
        IFileSystemObject[] GetObjects(bool includeDeleted);

        /// <summary>
        /// Creates a subdirectory.
        /// </summary>
        /// <param name="name">The name of the subdirectory.</param>
        /// <returns>An <see cref="IDirectory"/> instance representing the subdirectory.</returns>
        /// <exception cref="ArgumentNullException">The argument <paramref name="name"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException">The argument <paramref name="name"/> contains invalid characters.</exception>
        /// <exception cref="IndexAreaFullException">Cannot create directory because the index area is full.</exception>
        /// <exception cref="System.IO.PathTooLongException">The full path is too long.</exception>
        /// <exception cref="System.IO.IOException">An I/O exception occurred.</exception>
        IDirectory CreateDirectory(String name);

        /// <overloads>Creates or overwrites a file.</overloads>
        /// <summary>
        /// Creates or overwrites a file.
        /// </summary>
        /// <param name="name">The name of the file.</param>
        /// <returns>An <see cref="IFile"/> instance representing the subdirectory.</returns>
        /// <exception cref="ArgumentNullException">The argument <paramref name="name"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException">The argument <paramref name="name"/> contains invalid characters.</exception>
        /// <exception cref="IndexAreaFullException">Cannot create file because the index area is full.</exception>
        /// <exception cref="System.IO.PathTooLongException">The full path is too long.</exception>
        /// <exception cref="System.IO.IOException">An I/O exception occurred.</exception>
        IFile CreateFile(String name);

        /// <summary>
        /// Creates or overwrites a file while reserving space for it in the data area.
        /// </summary>
        /// <param name="name">The name of the file.</param>
        /// <param name="length">Specifies the maximum length of the file that is guaranteed to be available.</param>
        /// <returns>An <see cref="IFile"/> instance representing the subdirectory.</returns>
        /// <remarks>The <see cref="IFile"/> can grow larger than <paramref name="length"/>, but that space is not guaranteed to be available.</remarks>
        /// <exception cref="ArgumentNullException">The argument <paramref name="name"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException">The argument <paramref name="name"/> contains invalid characters.</exception>
        /// <exception cref="ArgumentOutOfRangeException">The argument <paramref name="length"/> is negative.</exception>
        /// <exception cref="IndexAreaFullException">Cannot create file because the index area is full.</exception>
        /// <exception cref="DataAreaFullException">Cannot create file because the data area is full.</exception>
        /// <exception cref="System.IO.PathTooLongException">The full path is too long.</exception>
        /// <exception cref="System.IO.IOException">An I/O exception occurred.</exception>
        IFile CreateFile(String name, Int64 length);

        /// <summary>
        /// Deletes the <see cref="IFileSystemObject"/> with the specified <paramref name="name"/>.
        /// </summary>
        /// <param name="name">The name of the <see cref="IFileSystemObject"/> to delete.</param>
        /// <exception cref="ArgumentNullException">The argument <paramref name="name"/> is <see langword="null"/>.</exception>
        /// <exception cref="IOException">An I/O exception occurred.</exception>
        /// <exception cref="PathNotFoundException">The specified <see cref="IFileSystemObject"/> cannot be found.</exception>
        void Delete(String name);

        /// <summary>
        /// Deletes this <see cref="IDirectory"/>.
        /// </summary>
        /// <param name="recurse">Specifies whether to delete any files and subdirectories as well.</param>
        /// <exception cref="InvalidOperationException">The directory is not empty, and <paramref name="recurse"/> was not specified.</exception>
        /// <exception cref="System.IO.IOException">An I/O exception occurred.</exception>
        void Delete(bool recurse);

        /// <summary>
        /// Deletes the <see cref="IDirectory"/> with the specified <paramref name="name"/>.
        /// </summary>
        /// <param name="name">The name of the <see cref="IDirectory"/> to delete.</param>
        /// <param name="recurse">Specifies whether to delete any files and subdirectories as well.</param>
        /// <exception cref="ArgumentNullException">The argument <paramref name="name"/> is <see langword="null"/>.</exception>
        /// <exception cref="IOException">An I/O exception occurred.</exception>
        /// <exception cref="DirectoryNotFoundException">The specified directory cannot be found.</exception>
        /// <exception cref="InvalidOperationException">The directory is not empty, and <paramref name="recurse"/> was not specified.</exception>
        void Delete(String name, bool recurse);

#if false
        /// <summary>
        /// Restores this <see cref="IDirectory"/> that was previously deleted.
        /// </summary>
        /// <param name="recurse">Specifies whether to restore any files and subdirectories as well.</param>
        /// <exception cref="InvalidOperationException">The directory is not deleted.</exception>
        /// <exception cref="IOException">An I/O exception occurred.</exception>
        /// <exception cref="IndexAreaFullException">Cannot create directory because the index area is full.</exception>
        void Resurrect(bool recurse);
#endif
    }
}
